/***
**  JQUERY MINISUGGEST PLUGIN
**	WRITTEN BY TOM ROMBAUT
**  Version 0.1
**  03/2010
**  DEPENDENCIES : JQUERY 1.3.1+ , JQUERY UI 1.7.2+
***/
var MiniSuggest = function(element, options) {
	var conf = $.extend({}, $.fn.minisuggest.defaults, options);
	var trigger = $(element);
	var suggest = $('<ul class="mini-suggest"></ul>');
	var currentdata = {};
	var selindex = 0;
	
	var _initialize = function() {
		$("body").append(suggest);
		trigger.focus(function(){_buildsuggest()});
		trigger.blur(function(event){
			setTimeout(function(){_hidesuggest()},500);
		});
		
		trigger.keyup(function(e){
			switch(e.keyCode){
				//LEFT & RIGHT:
				case 37:	
				case 39:	return true;
				//UP	
				case 38:	if($("li."+conf.hoverclass,suggest).length > 0){
								if($("li."+conf.hoverclass,suggest).prev().is("li")){
									var el = $("li."+conf.hoverclass,suggest).prev();
									$("li."+conf.hoverclass,suggest).removeClass(conf.hoverclass);
									el.addClass(conf.hoverclass);
								}
							}
							return false;
				//DOWN
				case 40:	if($("li."+conf.hoverclass,suggest).length > 0){
								if($("li."+conf.hoverclass,suggest).next().is("li")){
									var el = $("li."+conf.hoverclass,suggest).next();
									$("li."+conf.hoverclass,suggest).removeClass(conf.hoverclass);
									el.addClass(conf.hoverclass);
								}
							}else{
								$("li:first",suggest).addClass(conf.hoverclass);
							}
							return false;
				//TAB & ENTER
				case 13:	if($("li."+conf.hoverclass,suggest).length > 0){
								var key = $("li."+conf.hoverclass,suggest).attr("rel");
								_select(key);
							}
							return true;
				//ESC
				case 27:	_hidesuggest();
							return true;
				//BACKSPACE
				case 8:		
				default:	_buildsuggest();
				
			}
		});
		trigger.keydown(function(e){
			if(e.keyCode == 9){
				if($("li."+conf.hoverclass,suggest).length > 0){
					var key = $("li."+conf.hoverclass,suggest).attr("rel");
					_select(key);
				}
				return true;
			}
		});
	};
	var _showsuggest = function(){
		suggest.css({
			top		:	trigger.position().top + trigger.outerHeight(),
			left	:	trigger.position().left,
			width	:	trigger.innerWidth()
		});
		
		suggest.css("display","block");
	};
	var _hidesuggest = function(){
		suggest.css("display","none");
	};
	var _buildsuggest = function(){
		var val = "";
		if(conf.source != null)
			val = conf.source.attr("value");
		else
			val = trigger.attr("value");
		
		var params = conf.params;
		params.value = val;
		
		if($.isFunction(conf.getextraparams)){
			eparams = conf.getextraparams();
			for(key in eparams){
				params[key] = eparams[key];
			}
		}
		$.ajax({
			type	: conf.method,
			url		: conf.url,
			data	: params,
			dataType: conf.datatype,
			success	: function(data){
				currentdata = data;
				_fill(data);
			}
		}); 
	};
	var _fill = function(items){
		$("li",suggest).remove();
		var res = 0;
		for(var key in items){
			if((conf.maxresults > 0 && res < conf.maxresults) || conf.maxresults == 0){
				var li = $("<li rel='"+key+"'>"+items[key].label+"</li>")
				suggest.append(li);
				li.click(function(){
					var k = $(this).attr("rel");
					_select(k);
				});
				
				li.mouseover(function(){
					$("li",suggest).removeClass(conf.hoverclass);
					$(this).addClass(conf.hoverclass);
				});
				res++;
			}
		}
		if($("li",suggest).length > 0){
			_showsuggest();
		}else
			_hidesuggest();
	};	
	var _select = function(key){
		var item = currentdata[key];
		trigger.attr("value",item.label);
		if($.isFunction(conf.onselect))
			conf.onselect(item);
		_hidesuggest();
	};
	_initialize();
	return trigger;
};

/**
**	JQUERY PLUGIN
**/
(function($) {	
	$.fn.minisuggest = function(options) {
		return this.each(function() {
			var element = $(this);
			if (element.data('minisuggest')) return;
			var w = new MiniSuggest(this, options);
			element.data('minisuggest', w);
		});
	};
})(jQuery);

$.fn.minisuggest.defaults = {
	source				:	null,			//VALUE FROM OTHER SOURCE THAN TRIGGER (ELEMENT)
	hoverclass			:	"ms-select",	//CLASSNAME HOVER/SEL
	maxresults			:	0,				//MAX DISPLAYED RESULTS
	url					:	'/',			//AJAX REQUEST URL
	method				:	"POST",			//AJAX REQUEST METHOD
	datatype			: 	"json",			//AJAX REQUEST DATATYPE
	params				:	{action:"get"},	//DEFAULT AJAX PARAMS
	getextraparams		:	false,			//EXTRA FUNCTION TO RETREIVE PARAMS (OBJECT)
	onselect			:	false			//ON SELECT FUNCTION
};